package com.shiva.oms.logview.api.view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.JTree;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;

import org.apache.commons.lang3.StringUtils;

import com.eltima.components.ui.DatePicker;
import com.google.common.collect.Multimap;
import com.sf.shiva.oms.common.constant.LogTableConstant;
import com.shiva.oms.logview.api.control.MainFrameControl;
import com.shiva.oms.logview.api.model.LogDataTableModel;
import com.shiva.oms.logview.api.model.LogFileDirTreeModel;
import com.shiva.oms.logview.domain.ConnectCfg;
import com.shiva.oms.logview.domain.LogData;
import com.shiva.oms.logview.domain.QueryCond;
import com.shiva.oms.server.LogDataClassificateIndex;

/**
 * 
 * 
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID    DATE            PERSON            REASON
 *  1     2018年4月16日         LA.01367604           Create
 * ****************************************************************************
 * </pre>
 * 
 * @author LA.01367604
 * @version 1.0
 */
public class MainFrame{

    private Toolkit toolkit = Toolkit.getDefaultToolkit();// 定义工具包
    private JFrame frmLogview;
    private JScrollPane tableScrollPane;
    private JTable table;
    private JLabel countLabel;
    private JLabel fileNameLabel;
    private JPanel panel;
    private Panel topPanel;
    private Panel buttomPanel;
    private JSplitPane splitPane;
    private JSplitPane splitPane_1;
    private JTextPane textPane;
    private JCheckBox chckbxError;
    private JCheckBox chckbxWarn;
    private JCheckBox chckbxDebug;
    private JCheckBox chckbxInfo;
    private JCheckBox allCheckBox;
    private JTree tree;
    private JPopupMenu filePopupmenu;
    private JMenu hisFilesMenu;
    private JMenu hisConnMenu;
    private DatePicker startDatepick;
    private DatePicker endDatepick;
    private JMenuItem markItem;
    private JMenuItem ignoreItem;

    private MainFrameControl controler = new MainFrameControl();
    private LogDataClassificateIndex logDataClassificateIndex;
    private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Dir");
    private int rightClickRowIndex = -1;
    private LogFileDirTreeModel selectedFileNode;
    private QueryCond queryCond;
    private Map<String, Object> classIndexMap;
    private Map<String, Integer> levelMap = new HashMap<>();

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                try {
                    MainFrame window = new MainFrame();
                    window.frmLogview.setVisible(true);
                    window.splitPane.setDividerLocation(0.5); // 初始分割比例
                    window.splitPane_1.setDividerLocation(0.2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public MainFrame() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        Dimension screenSize = toolkit.getScreenSize(); // 获取屏幕的尺寸
        int screenWidth = screenSize.width; // 获取屏幕的宽
        int screenHeight = screenSize.height; // 获取屏幕的高

        frmLogview = new JFrame("日志解析");
        frmLogview.setTitle("LogView 1.0");
        frmLogview.setResizable(false);
        frmLogview.setBounds(100, 100, 975, 749);
        int height = frmLogview.getHeight();
        int width = frmLogview.getWidth();
        frmLogview.setLocation(screenWidth / 2 - width / 2, screenHeight / 2 - height / 2);// 设置窗口居中显示
        frmLogview.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmLogview.getContentPane().setLayout(null);

        initMainPanel();

        initMenuBar();
        
        initTopPanel();

        // initButtomPanel();

    }

    private void initMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        frmLogview.setJMenuBar(menuBar);

        JMenu mnNewMenu = new JMenu("文件");
        mnNewMenu.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuBar.add(mnNewMenu);

        JMenuItem mntmNewMenuItem_4 = new JMenuItem("打开日志文件");
        mntmNewMenuItem_4.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mntmNewMenuItem_4.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                JFileChooser jfc = new JFileChooser();
                jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
                jfc.showDialog(new JLabel(), "打开日志文件");
                File file = jfc.getSelectedFile();
                if (file == null) {
                    return;
                }
                if (file.isFile()) {
                    // System.out.println("文件:" + file.getAbsolutePath());
                    controler.setSelectedFileName(file.getName());
                    controler.createFilesTreeNode(file, tree, root);
                    panel.repaint();
                } else if (file.isDirectory()) {
                    System.out.println("文件夹:" + file.getAbsolutePath());
                    if (file.listFiles().length==0){
                        JOptionPane.showMessageDialog(panel, "当前目录无法获取文件", "获取文件", JOptionPane.WARNING_MESSAGE);
                    }
                    controler.createFilesTreeNode(file, file.listFiles(), tree, root);
                    panel.repaint();
                }
            }
        });
        mnNewMenu.add(mntmNewMenuItem_4);

        hisFilesMenu = new JMenu("打开历史文件");
        hisFilesMenu.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mnNewMenu.add(hisFilesMenu);
        controler.createHisFilesMenuItem(panel, hisFilesMenu, tree, root);

        JSeparator separator = new JSeparator();
        mnNewMenu.add(separator);

        JMenuItem mntmNewMenuItem = new JMenuItem("退出");
        mntmNewMenuItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mntmNewMenuItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent arg0) {
                frmLogview.setVisible(false);
                System.exit(0);
            }
        });
        mnNewMenu.add(mntmNewMenuItem);

        JMenu mnNewMenu_1 = new JMenu("工具");
        mnNewMenu_1.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuBar.add(mnNewMenu_1);

        JMenuItem mntmNewMenuItem_2 = new JMenuItem("连接管理");
        mntmNewMenuItem_2.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mntmNewMenuItem_2.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                ConnectCfg connectCfg = new ConnectCfg();
                ConnectCfgGui dialog = new ConnectCfgGui(frmLogview, connectCfg);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                controler.setDialogMidLocation(frmLogview, dialog);
                dialog.setVisible(true);
                controler.connectAndGetLogFiles(panel, connectCfg, tree, root);
            }
        });
        mnNewMenu_1.add(mntmNewMenuItem_2);

        JSeparator separator_1 = new JSeparator();
        mnNewMenu_1.add(separator_1);

        JMenuItem menuItem = new JMenuItem("新建连接");
        menuItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                ConnectCfg connectCfg = new ConnectCfg();
                NewConnectCfgGui dialog = new NewConnectCfgGui(frmLogview, connectCfg);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                controler.setDialogMidLocation(frmLogview, dialog);
                dialog.setVisible(true);
                controler.connectAndGetLogFiles(panel, connectCfg, tree, root);
            }
        });
        mnNewMenu_1.add(menuItem);

        hisConnMenu = new JMenu("上次连接");
        hisConnMenu.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mnNewMenu_1.add(hisConnMenu);
        controler.createHisConnMenuItem(panel, hisConnMenu, tree, root);

        JMenu menu = new JMenu("选项");
        menu.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuBar.add(menu);

        JMenuItem menuItem_1 = new JMenuItem("模糊查询");
        menuItem_1.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuItem_1.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent arg0) {
                queryCond = new QueryCond();
                QueryGui dialog = new QueryGui(frmLogview, queryCond);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                controler.setDialogMidLocation(frmLogview, dialog);
                dialog.setVisible(true);
                filterByKeyword(queryCond);
            }
        });
        menu.add(menuItem_1);

        JMenu mnHelper = new JMenu("帮助");
        mnHelper.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        menuBar.add(mnHelper);

        JMenuItem mntmNewMenuItem_3 = new JMenuItem("关于");
        mntmNewMenuItem_3.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        mntmNewMenuItem_3.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                AboutMe dialog = new AboutMe(frmLogview);
                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
                controler.setDialogMidLocation(frmLogview, dialog);
                dialog.setVisible(true);
            }
        });
        mnHelper.add(mntmNewMenuItem_3);
    }

    private void initTopPanel() {
        Panel topBoxPanel = new Panel();
        topBoxPanel.setBounds(0, 1, 969, 66);
        topBoxPanel.setBackground(SystemColor.control);
        frmLogview.getContentPane().add(topBoxPanel);

        Font font = new Font("Times New Roman", Font.BOLD, 12);// 字体
        Dimension dimension = new Dimension(177, 24);
        GridBagLayout gbl_topBoxPanel = new GridBagLayout();
        gbl_topBoxPanel.columnWidths = new int[] { 965, 0 };
        gbl_topBoxPanel.rowHeights = new int[] { 43, 23, 0 };
        gbl_topBoxPanel.columnWeights = new double[] { 0.0, Double.MIN_VALUE };
        gbl_topBoxPanel.rowWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE };
        
        topBoxPanel.setLayout(null);

        
        JPanel topPanel2 = new JPanel();
        topPanel2.setSize(969, 30);
        topPanel2.setLocation(0, 43);
        //frame.getContentPane().add(topPanel2);

        GridBagLayout gbl_topPanel2 = new GridBagLayout();
        gbl_topPanel2.columnWidths = new int[] { 380, 126, 117, 115, 121, 118, 0 };
        gbl_topPanel2.rowHeights = new int[] { 23, 0 };
        gbl_topPanel2.columnWeights = new double[] { 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, Double.MIN_VALUE };
        gbl_topPanel2.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
        topPanel2.setLayout(null);

        allCheckBox = new JCheckBox("All");
        allCheckBox.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        allCheckBox.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (table != null) {
                    if (allCheckBox.isSelected()) {
                        resetCheckBoxes();
                        filterByLevel();
                    } else {
                        resetNotSelectedCheckBoxes();
                        filterByLevel();
                    }
                }
            }
        });
        allCheckBox.setSelected(true);

        chckbxError = new JCheckBox("Error");
        chckbxError.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        chckbxError.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (table != null) {
                    filterByLevel();
                }
            }
        });
        chckbxError.setSelected(true);

        chckbxWarn = new JCheckBox("Warn");
        chckbxWarn.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        chckbxWarn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (table != null) {
                    filterByLevel();
                }
            }
        });
        chckbxWarn.setSelected(true);

        chckbxDebug = new JCheckBox("Debug");
        chckbxDebug.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        chckbxDebug.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (table != null) {
                    filterByLevel();
                }
            }
        });
        chckbxDebug.setSelected(true);

        chckbxInfo = new JCheckBox("Info");
        chckbxInfo.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        chckbxInfo.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (table != null) {
                    filterByLevel();
                }
            }
        });
        chckbxInfo.setSelected(true);

        
        topPanel = new Panel();
        topPanel.setSize(969, 40);
        topPanel.setLocation(0, 1);
        topPanel.setBackground(SystemColor.control);
        //frame.getContentPane().add(topPanel);
        GridBagLayout gbl_topPanel = new GridBagLayout();
        gbl_topPanel.columnWidths = new int[] { 165, 229, 25, 241, 142, 122, 22, 0 };
        gbl_topPanel.rowHeights = new int[] { 24, 0 };
        gbl_topPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,  Double.MIN_VALUE };
        gbl_topPanel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
        topPanel.setLayout(null);

        JLabel label = new JLabel("选择时间范围：");
        label.setBounds(42, 10, 98, 28);
        topPanel.add(label);
        label.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        
        Date nowDateTime = new Date();// 当前时间
        String DefaultFormat = "yyyy-MM-dd HH:mm:ss";// 格式
        startDatepick = new DatePicker(nowDateTime, DefaultFormat, font, dimension);
        startDatepick.getInnerTextField().setFont(new Font("微软雅黑", Font.PLAIN, 12));
        startDatepick.setBounds(150, 10, 160, 28);
        controler.setDateTimePicker(startDatepick);
        topPanel.add(startDatepick);
        
        JLabel label_1 = new JLabel("至");
        label_1.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        label_1.setSize(12, 28);
        label_1.setLocation(335, 10);
        topPanel.add(label_1);
        
        endDatepick = new DatePicker(nowDateTime, DefaultFormat, font, dimension);
        endDatepick.getInnerTextField().setFont(new Font("微软雅黑", Font.PLAIN, 12));
        endDatepick.setBounds(375, 10, 160, 28);
        controler.setDateTimePicker(endDatepick);
        topPanel.add(endDatepick);
        
        JButton button_1 = new JButton("查询");
        button_1.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        button_1.setBounds(601, 10, 80, 28);
        topPanel.add(button_1);
        button_1.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent arg0) {
                Date startTime = (Date) startDatepick.getValue();
                Date endTime = (Date) endDatepick.getValue();
                filterByTime(startTime, endTime);
            }
        });
        
        JButton button = new JButton("刷新");
        button.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        button.setBounds(736, 10, 80, 28);
        topPanel.add(button);
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent arg0) {
                reset();
            }
        });
        
        topBoxPanel.add(topPanel);

        
	    GridBagConstraints gbc_allCheckBox = new GridBagConstraints();
	    allCheckBox.setBounds(40, 2, 120, 22);
	    topPanel2.add(allCheckBox, gbc_allCheckBox);
     
	    GridBagConstraints gbc_chckbxError = new GridBagConstraints();
	    chckbxError.setBounds(180, 2, 120, 22);
	    topPanel2.add(chckbxError);
        
        GridBagConstraints gbc_chckbxWarn = new GridBagConstraints();
        chckbxWarn.setBounds(320, 2, 120, 22);
        topPanel2.add(chckbxWarn);
          
        GridBagConstraints gbc_chckbxInfo = new GridBagConstraints();
        chckbxInfo.setBounds(460, 2, 120, 22);
        topPanel2.add(chckbxInfo);
          
        GridBagConstraints gbc_chckbxDebug = new GridBagConstraints();
        chckbxDebug.setBounds(600, 2, 80, 22);
        topPanel2.add(chckbxDebug);

        topBoxPanel.add(topPanel2);
    }

    private void initMainPanel() {
        panel = new JPanel();
        panel.setBounds(0, 73, 969, 617);
        panel.setBackground(SystemColor.control);
//      panel.setPreferredSize(new Dimension(frame.getWidth(), frame.getHeight()));

        JMenuItem loadItem = new JMenuItem("解析");
        loadItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        loadItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (controler.isParsingInProgress()) {
                    System.out.println("正在解析文件，请稍后再试");
                } else if (selectedFileNode != null) {
                    controler.startParseLogFile(selectedFileNode);
                    load();
                }
            }
        });
        JMenuItem delNodeItem = new JMenuItem("删除");
        delNodeItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        delNodeItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (selectedFileNode != null) {
                    System.out.println("delete：" + selectedFileNode.getNodeName());
                    TreePath currentSelection = tree.getSelectionPath();
                    if (currentSelection != null) {
                        DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelection.getLastPathComponent());
                        MutableTreeNode parent = (MutableTreeNode) (currentNode.getParent());
                        if (parent != null) {
                            DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
                            model.removeNodeFromParent(currentNode);
                            panel.repaint();
                            return;
                        }
                    }
                }
            }
        });

        markItem = new JMenuItem("标记/取消标记");
        markItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        markItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (controler.isParsingInProgress()) {
                    System.out.println("正在解析文件，请稍后再试");
                } else if (rightClickRowIndex >= 0) {
                    // System.out.println("已标记：" + rightClickRowIndex);
                    LogDataTableModel model = (LogDataTableModel) table.getModel();
                    LogData data = model.getRow(rightClickRowIndex);
                    if (data.isMarked()) {
                        data.setMarked(false);
                        controler.setOneRowBackgroundColor(table, Color.blue);
                    } else {
                        data.setMarked(true);
                        controler.setOneRowBackgroundColor(table, Color.blue);
                    }
                    panel.repaint();
                }
            }
        });

        ignoreItem = new JMenuItem("不看此类");
        ignoreItem.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        ignoreItem.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                if (controler.isParsingInProgress()) {
                    System.out.println("正在解析文件，请稍后再试");
                } else if (rightClickRowIndex >= 0) {
                    LogDataTableModel model = (LogDataTableModel) table.getModel();
                    LogData data = model.getRow(rightClickRowIndex);
                    String clazz = data.getClazz();
                    System.out.println("不看此类：" + clazz);
                    filterByClazz(clazz);
                    // createTableFilter(TableColumns.CLASS.getColumn(), clazz);
                }
            }
        });
        
        splitPane = new JSplitPane();
        splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);

        splitPane.setPreferredSize(new Dimension(panel.getWidth(), panel.getHeight()));

        splitPane_1 = new JSplitPane();
        splitPane.setLeftComponent(splitPane_1);

        JScrollPane scrollPane_2 = new JScrollPane();
        splitPane_1.setLeftComponent(scrollPane_2);

        table = new JTable();
        table.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                int rowIndex = table.rowAtPoint(e.getPoint());// 得到table的行号
                if (controler.isParsingInProgress()) {
                    System.out.println("正在解析文件，请稍后再试");
                } else if (rowIndex > -1) {
                    if (SwingUtilities.isRightMouseButton(e)) {
                        rightClickRowIndex = rowIndex;
                        JPopupMenu popupmenu = controler.createPopMenu(markItem, ignoreItem);
                        popupmenu.show(e.getComponent(), e.getX(), e.getY());
                    } else {
                        controler.fillLogDetailText(textPane, table, rowIndex, queryCond);
                    }
                }
            }
        });
        
        tableScrollPane = new JScrollPane(table);
        tableScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        splitPane_1.setRightComponent(tableScrollPane);

        tree = new JTree();
        tree.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent e) {
                int n = tree.getRowForLocation(e.getX(), e.getY());
                if (n < 0) {
                    return;
                }
                TreePath selTree = tree.getPathForRow(n);
                DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) selTree.getLastPathComponent();
                if (selNode.getUserObject() instanceof String) { // 根节点不做响应处理
                    return ;
                }
                if (SwingUtilities.isRightMouseButton(e)) {
                    if (selNode.isLeaf()) {
                        System.out.println("leaf: " + selNode.getUserObject().toString());
                        selectedFileNode = (LogFileDirTreeModel) selNode.getUserObject();
                        filePopupmenu = controler.createPopMenu(loadItem, delNodeItem);
                        filePopupmenu.show(e.getComponent(), e.getX(), e.getY());
                    } else {
                        System.out.println("Dir: " + selNode.getUserObject().toString());
                        if (selNode.getParent() != null) {
                            filePopupmenu = controler.createPopMenu(delNodeItem);
                            filePopupmenu.show(e.getComponent(), e.getX(), e.getY());
                        }
                    }
                } else if (e.getClickCount() == 2) { // 双击
                    if (controler.isParsingInProgress()) {
                        System.out.println("正在解析文件，请稍后再试");
                    } else if (selNode.isLeaf()) {
                        selectedFileNode = (LogFileDirTreeModel) selNode.getUserObject();
                        controler.startParseLogFile(selectedFileNode);
                        load();
                    }
                }
            }
        });
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
        tree.setModel(new DefaultTreeModel(new DefaultMutableTreeNode("Files") {}));
        scrollPane_2.setViewportView(tree);

        JScrollPane scrollPane_1 = new JScrollPane();
        scrollPane_1.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        splitPane.setRightComponent(scrollPane_1);

        textPane = new JTextPane();
        textPane.setEditable(false);
        textPane.setBackground(new Color(255, 245, 238));
        scrollPane_1.setViewportView(textPane);

        panel.add(splitPane);
        frmLogview.getContentPane().add(panel);

    }

    private void initButtomPanel() {
        buttomPanel = new Panel();
        buttomPanel.setBounds(0, 627, 751, 22);
        buttomPanel.setBackground(SystemColor.control);
        frmLogview.getContentPane().add(buttomPanel);
        GridBagLayout gbl_buttomPanel = new GridBagLayout();
        gbl_buttomPanel.columnWidths = new int[] { 392, 149, 66, 138, 0 };
        gbl_buttomPanel.rowHeights = new int[] { 22, 0 };
        gbl_buttomPanel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
        gbl_buttomPanel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
        buttomPanel.setLayout(gbl_buttomPanel);

        fileNameLabel = new JLabel(); // selectedFileName
        GridBagConstraints gbc_fileNameLabel = new GridBagConstraints();
        gbc_fileNameLabel.insets = new Insets(0, 0, 0, 5);
        gbc_fileNameLabel.gridx = 1;
        gbc_fileNameLabel.gridy = 0;
        buttomPanel.add(fileNameLabel, gbc_fileNameLabel);

        countLabel = new JLabel("");
        GridBagConstraints gbc_countLabel = new GridBagConstraints();
        gbc_countLabel.fill = GridBagConstraints.BOTH;
        gbc_countLabel.gridx = 3;
        gbc_countLabel.gridy = 0;
        buttomPanel.add(countLabel, gbc_countLabel);

    }

    ////////////////////////////////////////
    //             控制方法区
    ///////////////////////////////////////
    private void resetCheckBoxes() {
        allCheckBox.setSelected(true);
        chckbxError.setSelected(true);
        chckbxWarn.setSelected(true);
        chckbxDebug.setSelected(true);
        chckbxInfo.setSelected(true);
    }

    private void resetNotSelectedCheckBoxes() {
        allCheckBox.setSelected(false);
        chckbxError.setSelected(false);
        chckbxWarn.setSelected(false);
        chckbxDebug.setSelected(false);
        chckbxInfo.setSelected(false);
    }

    private void reset() {
        if (controler.isParsingInProgress()) {
            System.out.println("正在解析文件，请稍后再试");
        } else {
            resetCheckBoxes();
            queryCond = null;
            fresh(controler.getList(), true);
        }
    }

    /**
     * 设置显示各级别数量
     * 
     * @author LA.01367604-2018年5月5日
     */
    public void setLevelCheckBox(Map<String, Object> indexMap) {
        // Map<String, Object> categoryMap = controler.getCategoryNames();
        if (indexMap == null || indexMap.isEmpty()) {
            return;
        }
        Multimap<String, LogData> map = (Multimap<String, LogData>) indexMap.get(LogTableConstant.LEVEL_ATTR);
        int errCount = (map.get(LogTableConstant.LEVEL_ERROR) != null) ? map.get(LogTableConstant.LEVEL_ERROR).size() : 0;
        int warnCount = (map.get(LogTableConstant.LEVEL_WARN) != null) ? map.get(LogTableConstant.LEVEL_WARN).size() : 0;
        int infoCount = (map.get(LogTableConstant.LEVEL_INFO) != null) ? map.get(LogTableConstant.LEVEL_INFO).size() : 0;
        int debugCount = (map.get(LogTableConstant.LEVEL_DEBUG) != null) ? map.get(LogTableConstant.LEVEL_DEBUG).size() : 0;
        chckbxError.setText("Error(" + errCount + ")");
        chckbxWarn.setText("Warn(" + warnCount + ")");
        chckbxInfo.setText("Info(" + infoCount + ")");
        chckbxDebug.setText("Debug("+debugCount +")");
        allCheckBox.setText("All(" + controler.getTableDatas(table).size() + ")");
    }

    /**
     * 刷新列表时动态设置显示各级别数量
     * 
     * @param list
     * @author LA.01367604-2018年5月5日
     */
    private void setLevelCheckBox(List<LogData> list) {
        if (list == null || list.isEmpty()) {
            return;
        }
        levelMap.clear();
        levelMap.put(LogTableConstant.LEVEL_ERROR, 0);
        levelMap.put(LogTableConstant.LEVEL_WARN, 0);
        levelMap.put(LogTableConstant.LEVEL_INFO, 0);

        list.stream().forEach(data -> {
            if (LogTableConstant.LEVEL_ERROR.equals(data.getLevel().toString())) {
                levelMap.replace(LogTableConstant.LEVEL_ERROR, levelMap.get(LogTableConstant.LEVEL_ERROR)+1);
            } else if(LogTableConstant.LEVEL_WARN.equals(data.getLevel().toString())) {
                levelMap.replace(LogTableConstant.LEVEL_WARN, levelMap.get(LogTableConstant.LEVEL_WARN)+1);
            } else if(LogTableConstant.LEVEL_INFO.equals(data.getLevel().toString())) {
                levelMap.replace(LogTableConstant.LEVEL_INFO, levelMap.get(LogTableConstant.LEVEL_INFO)+1);
            } else if(LogTableConstant.LEVEL_DEBUG.equals(data.getLevel().toString())) {
                levelMap.replace(LogTableConstant.LEVEL_DEBUG, levelMap.get(LogTableConstant.LEVEL_DEBUG)+1);
            }
        });
        allCheckBox.setText("All(" + list.size() + ")");
        chckbxError.setText("Error(" + levelMap.get(LogTableConstant.LEVEL_ERROR) + ")");
        chckbxWarn.setText("Warn(" + levelMap.get(LogTableConstant.LEVEL_WARN) + ")");
        chckbxInfo.setText("Info(" + levelMap.get(LogTableConstant.LEVEL_INFO) + ")");
        chckbxDebug.setText("Debug(" + levelMap.get(LogTableConstant.LEVEL_DEBUG) + ")");
    }
    
    /**
     * 加载解析的数据到表格中
     * 
     * @param showList
     * @param headNames
     * @author LA.01367604-2018年5月5日
     */
    private void load() {
        LogDataTableModel model = new LogDataTableModel(controler.getList(), controler.getHeaderNames(), controler.getParseProperties());
        table.setModel(model);
        // table.revalidate();
        // initLevelCheckBox();// 设置级别个数
        logDataClassificateIndex = new LogDataClassificateIndex(this, controler.getList());// 后台线程创建索引，并设置级别个数
        resetCheckBoxes();
        textPane.setText("");
        // countLabel.setText(String.format(countLabelStrFormat, showList.size()));
        // fileNameLabel.setText(selectedFileName);
        panel.repaint();
    }

    /**
     * 重置刷新数据：表格、底部label显示等
     * 
     * @param showList
     * @author LA.01367604-2018年4月18日
     */
    private void fresh(List<LogData> showList, boolean isNeedRebuildIndex) {
        if (table.getModel() instanceof DefaultTableModel) {// 初始状态，table未加载
            return;
        }
        LogDataTableModel model = (LogDataTableModel) table.getModel();
        model.clear();// 清除原有行
        model.setDatas(showList);
        if (isNeedRebuildIndex) {
            logDataClassificateIndex = new LogDataClassificateIndex(this, showList);// 后台线程创建索引，并设置级别个数
        }
        textPane.setText("");
        // countLabel.setText(String.format(countLabelStrFormat, showList.size()));
        // fileNameLabel.setText(selectedFileName);
        panel.repaint();
    }

    /**
     * 根据日志级别过滤（checkbox）
     * 
     * @author LA.01367604-2018年4月18日
     */
    private void filterByLevel() {
        if (controler.isParsingInProgress()) {
            System.out.println("正在解析文件，请稍后再试");
            return;
        } else if (allCheckBox ==null || chckbxError == null || chckbxWarn == null || chckbxInfo == null || chckbxDebug == null) {
            return;
        }
        List<LogData> showList = null;
        if (table.getModel() instanceof DefaultTableModel) {// table未加载
            return;
        } else if (this.classIndexMap == null || this.classIndexMap.isEmpty()) {
            showList = SynOldFilterByLevel();
        } else {
            showList = AsynIndexFilterByLevel();
        }
        fresh(showList, false);
    }

    protected List<LogData> AsynIndexFilterByLevel() {
        Multimap<String, LogData> map = (Multimap<String, LogData>) this.classIndexMap.get(LogTableConstant.LEVEL_ATTR);
        Set<LogData> datas = new TreeSet<LogData>(new Comparator<LogData>() {

            @Override
            public int compare(LogData o1, LogData o2) {
                return o1.getId() - o2.getId(); // 正序
            }

        });
        if (chckbxError.isSelected()) {
            datas.addAll(map.get(LogTableConstant.LEVEL_ERROR));
        }
        if (chckbxWarn.isSelected()) {
            datas.addAll(map.get(LogTableConstant.LEVEL_WARN));
        }
        if (chckbxInfo.isSelected()) {
            datas.addAll(map.get(LogTableConstant.LEVEL_INFO));
        }
        if (chckbxDebug.isSelected()) {
            datas.addAll(map.get(LogTableConstant.LEVEL_DEBUG));
        }
        return new ArrayList<>(datas);
    }

    protected List<LogData> SynOldFilterByLevel() {
        List<String> selectedLevel = new ArrayList<>();
        if (chckbxError.isSelected()) {
            selectedLevel.add("ERROR");
        }
        if (chckbxWarn.isSelected()) {
            selectedLevel.add("WARN");
        }
        if (chckbxInfo.isSelected()) {
            selectedLevel.add("INFO");
        }
        if (chckbxDebug.isSelected()) {
            selectedLevel.add("DEBUG");
        }
        return controler.filterByLevel(controler.getTableDatas(table), selectedLevel);
    }

    private void filterByClazz(String clazzName) {
        List<LogData> showList = controler.filterByClazz(table, clazzName);
        fresh(showList, true);
    }

    private void filterByKeyword(QueryCond queryCond) {
        if (controler.isParsingInProgress()) {
            System.out.println("正在解析文件，请稍后再试");
        } else if (queryCond != null && StringUtils.isNotBlank(queryCond.getKeyword())) {
            List<LogData> showList = controler.filterByKeyword(table, queryCond.getKeyword());
            fresh(showList, true);
        }
    }

    private void filterByTime(Date startTime, Date endTime) {
        if (controler.isParsingInProgress()) {
            System.out.println("正在解析文件，请稍后再试");
            return;
        } else if (startTime == null || endTime == null ||StringUtils.isBlank(startTime.toString()) || StringUtils.isBlank(endTime.toString())) {
            return;
        }
        List<LogData> showList = controler.filterByTime(table, startTime, endTime);
        fresh(showList, true);
        resetCheckBoxes();
    }

    public Map<String, Object> getClassIndexMap() {
        return classIndexMap;
    }

    public void setClassIndexMap(Map<String, Object> classIndexMap) {
        this.classIndexMap = classIndexMap;
    }
}
